Your First Software Project
A series of notes for non-technical founders and stakeholders who are working on a software project for the first time.
I've worked in software for over a decade, and I have a good sense of what increases and decreases a project's chance of success. These notes aim to increase clarity and encourage collaboration on both sides of the table.
If you haven't worked in software, you may be used to projects that have a fixed definition of success, requirements, timeline and budget. Your software projects will have none of those, which is a good thing. Why is this? Read on.
Writing software is creative, not mechanical
Some people think that writing software is like hiring construction workers to follow a blueprint. Instead, it's more akin to being both builder and architect and alternating between the two. You do some initial blueprinting (shaping), then build some. Get feedback, and repeat.
To be fair, some software developers like to focus exclusively on the building aspect & ignore other factors because writing code is discrete, legible, and within their domain. These are the developers who will do exactly as they are told with no regard to whether or not it increases the project's chance of success. Be wary of hiring these kinds of developers unless you are an experienced technical manager who knows how to corral them.
There are no guarantees; only increasing and decreasing chances of success.
What 'success' means is project-dependent. But in most cases, there is no way to 100% guarantee the success of a project. Software engineering is a game of betting and taking calculated risks. You can only do things that increase and decrease a project's chance of success.
Working on software requires an uncertainty mindset.
Software development requires experimentation
Software is reusable. If a problem has a recurring, known solution, then there are off-the-shelf solutions that can be re-used. However, if you are working with people to create custom software, then the problem in some fashion, by definition, is novel. It could be the uniqueness of your idea or your unique competitive advantage. Either way, it means solving new problems.
Coming up with creative solutions to problems is something that requires trial and error. Experimentation and failure are part of the process.
It's counterintuitive, but an environment that allows for failure increases a project's chance of success.
Experimenting requires a hypothesis. Everyone has assumptions at the start of a project. Experimenting is a way to prove or disprove those assumptions. There is a difference between experimenting and throwing things at the wall and seeing what sticks. Another bristle of the uncertainty is that it is less efficient. That's a cost for this process. If the process could be made more predictable and efficient, it would be made into reusable code or software, and you wouldn't have to build them. While you may end up re-doing work and throwing work away, the process in the long term gets you to a successful project faster.
Third-party solutions come with constraints
If a problem has been solved and is not unique, then it is likely smart to leverage someone else's existing solutions. For example, running a server to send email is complex and expensive, and would probably cost you at least $100,000/year to run, if not more. Contrast with a product like Sendgrid, which starts at free and will let you send up to 100,000 emails for $15/month.
However, whenever you use a third-party service, they will come with constraints. It's up to them, not me, how we can leverage, extend, and modify their behavior. Since 3rd parties are orders of magnitude cheaper, it's often correct to accept and work within these constraints instead of fighting them.
Share The Problem
Since building a software project The biggest mistake I see first time software project owners make is refusing to share the problem with their engineering staff. Most developers are creative, and figuring out how to solve the problem. If you hand a developer a "project requirements document" you are wasting their potential to help you find the best technical solution to your problem.
Doing the work is a form of research
Upfront planning is important and often discounted(again, see shaping), however there are always going to be problems that cannot be discovered until you are in the work. Every project has unknowns, some of which can be found ahead of time, others which can only be unsurfaced by work.
Software development is incremental, not fixed.
All of the reasons above are why software firms evangelize "Agile" development. That words means different things to different people, but at the core, its about having a process that focuses on multiple iterations over a single fixed project plan. Since software is a creative practice of experimenting, building, and research-through-building, it makes the most sense to have a practice of working in smaller discrete chunks, getting feedback, and iterating.
This process allows software to move faster, and adjust to new conditions and insights quickly. This speed helps increase your chances of success.
However, be wary that working in an 'agile' fashion is often used to excuse bad behavior:
- Agile development does not excuse you from doing any upfront research or planning. Agile should be use to make adjustments in how work is getting first and foremost, less so in defining goals and what is getting done. You cannot aim for success if the definition of success is a moving target.
- Just because you can make a change doesn't mean you should. Left unchecked iteration can lead to bike shedding (see Parkinson's Law of Triviality in adages:)
"people within an organization commonly or typically give disproportionate weight to trivial issues."
To avoid triviality, it's also best to reduce feedback loops that hold up development. I've worked on many projects that get held up for weeks because the client wants to approve every font choice and pixel. The project was no better off for it in the end.
"Fast, Cheap, or Good" is bullshit
Have you heard the saying "Fast, Cheap & Good, pick two?" Bullshit. speed and quality go hand in hand. The quicker you can iterate on software, the quicker you can find working solutions, the quicker you can fix problems, and consequently the higher quality software product you have.
What do I mean when I say "quality?" Quality software is software with a higher chance of success, however you define it.
Estimates are (mostly) bullshit
How much does it cost to build a website?
You can set up Squarespace for $150/year. You can have a custom theme for Wordpress developed for a few thousand dollars. You can spend $3 million dollars on a website project and still fail
Above explains why software projects are required to be uncertain. If a developer gives you an estimate, it's fiction.
Instead, it's better to focus on appetite. How much are you willing to invest in solving a problem? Knowing that constraint, it's easier to find solutions that can work within it. It might mean getting something not custom but still works. Sometimes an appetite is unreasonable and expectations can then be identified and adjusted.
All Egos Are Left At The Door
The No.1 difference I've seen in successful project owners vs. failures? The failures can't let their ego go. Same with the worst engineers I've worked for. They make technical decisions based on comfort levels and personal preferences instead of what's best for the project.
When it comes to a project, I like the 'Third Person Lens' for talking about it. There's you, there's me, and there is the project. We are both free to talk the project in a non-personal fashion. We both share the goal of increasing the quality of the project as best we can.
Ideas and changes should be evaluated through the lens of "does this increase the project's chance of success?" almost exclusively. Changes should not be made only because one person changed their mind.
This also relates to keeping a mindset open to experimentation. It requires failure which can be scary. Projects should be a place where people are open to experimenting and feel they can fail safely. If you are unwilling to fail you are unable to succeed.
I have worked on projects where it became clear the only success metric was "Does the stakeholder like it?" When in these situations, the only solution I have found is to solider on, do as asked, and be ready to deal with the stakeholder at the end of the project, when they discover the market doesn't care one bit if they like it or not. Don't be that stakeholder.
Having said that, we are all human. Putting the project ahead of egos does not excuse harsh or sociopathic behavior. Working on a project with people requires empathy, even more so when we are trying to create an environment with open failure and constructive criticism.
Build Less, With Confidence
Putting it all together, what does a successful software project look like?
- It defines and commits to a definition of success, over a fixed definition of 'requirements' and 'scope.'
- It has upfront research to define assumptions, constraints, and potential solutions, and no-gos.
- It leverages existing solutions to solved problems, and focuses effort on novel problems.
- Plans are made based on appetite, not estimates.
- It solves novel problems through iteration and experimentation.
- It aims to increase iteration speed by reducing approval cycles.
- It's focused on helping the project, and not stroking people's egos.